<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small"
             :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="服务名" prop="serviceId">
        <el-select
          style="width:295px;"
          v-model="queryParams.serviceId"
          clearable
          filterable
          placeholder="请选择服务名,支持搜索过滤"
          @change="val => handleStoreQueryParams(storeServiceNameKey, val)"
          @keyup.enter.native="handleQuery"
        >
          <el-option
            v-for="item in serviceOptions"
            :key="item.id"
            :label="item.name"
            :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="链路ID" prop="traceId">
        <el-input v-model="queryParams.traceId" clearable placeholder="链路ID,仅支持精确查询" style="width:295px;"
                  @keyup.enter.native="handleQuery"/>
      </el-form-item>
      <el-form-item label="处理人" prop="disposeUser">
        <el-select v-model="queryParams.disposeUser" filterable clearable placeholder="负责人,选项支持模糊过滤"
                   style="width: 295px;"
                   @change="val => handleStoreQueryParams(storeDisposeUserKey, val)"
                   @keyup.enter.native="handleQuery">
          <el-option :key="self.value" :label="self.label"
                     :value="self.value"></el-option>
          <el-option v-for="user in userOptions" :key="user.userId" :label="user.name"
                     :value="user.userId"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="状态" prop="problemStatus">
        <el-select
          style="width:295px;"
          v-model="queryParams.problemStatus"
          clearable
          multiple
          placeholder="请选择缺陷状态,支持多选"
          @change="val => handleStoreQueryParams(storeStatusKey, val)"
          @keyup.enter.native="handleQuery"
        >
          <el-option
            v-for="item in statusOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="缺陷等级" prop="problemLevels">
        <el-select
          style="width:295px;"
          v-model="queryParams.problemLevels"
          clearable
          multiple
          placeholder="请选择缺陷等级,支持多选"
          @change="val => handleStoreQueryParams(storeProblemLevelKey, val)"
          @keyup.enter.native="handleQuery"
        >
          <el-option
            v-for="item in problemLevelOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="缺陷原因" prop="problemCauses">
        <el-select
          style="width:295px;"
          v-model="queryParams.problemCauses"
          clearable
          multiple
          placeholder="请选择缺陷原因,支持多选"
          @change="val => handleStoreQueryParams(storeProblemCauseKey, val)"
          @keyup.enter.native="handleQuery"
        >
          <el-option
            v-for="item in problemCauseOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="记录时间" prop="recordTimes">
        <el-date-picker
          style="width:335px;"
          v-model="queryParams.recordTimes"
          clearable
          type="datetimerange"
          :picker-options="pickerOptions"
          range-separator="-"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          align="right"
          value-format="yyyy-MM-dd HH:mm:ss"
          format="yyyy-MM-dd HH:mm:ss"
          placeholder="创建缺陷的时间"
          @change="val => handleStoreQueryParams(storeProblemTimesKey, val)"
          @keyup.enter.native="handleQuery"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item label="告警时间" prop="alarmTimes">
        <el-date-picker
          style="width:335px;"
          v-model="queryParams.alarmTimes"
          clearable
          type="datetimerange"
          :picker-options="pickerOptions"
          range-separator="-"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          align="right"
          value-format="yyyy-MM-dd HH:mm:ss"
          format="yyyy-MM-dd HH:mm:ss"
          @change="val => handleStoreQueryParams(storeAlarmTimesKey, val)"
          @keyup.enter.native="handleQuery"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item label="异常标识" prop="stackHash">
        <el-input v-model="queryParams.stackHash" placeholder="异常标识,仅支持精确查询" clearable style="width:215px;"
                  @keyup.enter.native="handleQuery"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8" style="display: flex; align-items: center;">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-notebook-1"
          size="mini"
          @click="handleDict"
          v-hasPermi="['hawk-eye:problem-record:add']"
        >字典维护
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-circle-close"
          size="mini"
          :disabled="multiple"
          @click="handleClose"
          v-hasPermi="['hawk-eye:problem-record:edit']"
        >关闭缺陷
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          style="color: red;"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['hawk-eye:problem-record:remove']"
        >删除
        </el-button>
      </el-col>
      <div style="margin-left: auto;">
        <el-link
          style="font-size: 13px; color: blue;"
          :underline="false"
          @click="handleDoc">
          什么是缺陷管理？
        </el-link>
      </div>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table ref="table" v-loading="loading" :data="recordList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center"/>
      <el-table-column label="缺陷名称" align="center" show-overflow-tooltip prop="problemName" width="150"/>
      <el-table-column label="所属服务" align="center" prop="serviceName"
                       :formatter="(row, column, cellValue, index) =>
                       `${row.serviceCnName ? row.serviceCnName:'unknown'}(${row.serviceZnName ? row.serviceZnName:'unknown'})`"
                       :show-overflow-tooltip="true" width="180"/>
      <el-table-column label="缺陷等级" align="center" prop="problemLevelText" width="90">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.problemLevel" :style="{background: problemLevelColors[scope.row.problemLevel - 1]}"
                  class="tag" type="dark">{{
            scope.row.problemLevelText }}
          </el-tag>
          <span v-else></span>
        </template>
      </el-table-column>
      <el-table-column label="缺陷原因" align="center" prop="problemCauseText" width="90">
        <template #default="scope">
          <el-tooltip v-if="scope.row.problemCauseDescription" :content="scope.row.problemCauseDescription"
                      placement="top">
                <span style="color: #1890ff; cursor: pointer;">
                  {{ scope.row.problemCauseText }}
                </span>
          </el-tooltip>
          <span v-else>{{scope.row.problemCauseText}}</span>
        </template>
      </el-table-column>
      <el-table-column label="记录时间" align="center" prop="recordTime" width="150">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.recordTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="告警时间" align="center" prop="alarmTime" width="150">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="处理人" align="center" prop="disposeUserName" show-overflow-tooltip width="90"/>
      <el-table-column label="状态" align="center" prop="status"
                       :formatter="(row, column, cellValue, index) => {
                         let text = statusOptions.filter(e => e.value === row.status).map(e => e.label);
                         return text ? text : '';
                       }" width="90"/>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['hawk-eye:problem-record:edit']"
          >编辑
          </el-button>
          <el-button
            v-if="scope.row.status == 0"
            size="mini"
            type="text"
            icon="el-icon-check"
            @click="handleResolve(scope.row)"
            v-hasPermi="['hawk-eye:problem-record:edit']"
          >解决
          </el-button>
          <el-button
            v-else
            size="mini"
            type="text"
            icon="el-icon-magic-stick"
            @click="handleActivate(scope.row)"
            v-hasPermi="['hawk-eye:problem-record:edit']"
          >激活
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="Number(total)>0"
      :total="Number(total)"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <modal-form ref="modalForm" @submitted="getList"></modal-form>
    <dict-drawer ref="dictDrawer"/>
  </div>
</template>

<script>
  import {
    problemPageList,
    addProblem,
    resolveProblem,
    activateProblem,
    closeProblem,
    updateProblem,
    removeProblem,
    dictListByType
  } from "@/api/hawkeye/problem";
  import {serviceNameList, userListNotSelf} from "@/api/hawkeye/service";
  import {formatDate} from "@/utils/index";
  import DictDrawer from "./modules/DictDrawer";
  import ModalForm from "./modules/ModalForm";

  export default {
    name: "ProblemRecord",
    components: {
      DictDrawer,
      ModalForm
    },
    data() {
      return {
        // 遮罩层
        loading: true,
        // 选中数组
        ids: [],
        // 非单个禁用
        single: true,
        // 非多个禁用
        multiple: true,
        // 显示搜索条件
        showSearch: true,
        showHighLevelSearch: false,
        // 总条数
        total: 0,
        // 【请填写功能名称】表格数据
        recordList: [],
        // 弹出层标题
        title: "",
        // 是否显示弹出层
        open: false,
        // 查询参数
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          problemStatus: [0, 1]
        },
        dateRange: [],
        // 表单参数
        form: {},
        // 表单校验
        rules: {
          problemLevel: [
            {required: true, message: "缺陷等级不能为空", trigger: "blur"}
          ],
          problemDesc: [
            {required: true, message: "缺陷描述不能为空", trigger: "blur"}
          ]
        },
        userOptions: [],
        self: {label: '仅看自己', value: -1},
        serviceOptions: [],
        problemLevelOptions: [],
        problemLevel: 'problemLevel',
        problemLevelColors: ['#f66666', '#f8962e', '#1a24fd', '#4fabf6', '#0cdc21'],
        pickerOptions: {
          shortcuts: [
            {
              text: '近5分钟',
              onClick(picker) {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - 600 * 500);
                picker.$emit('pick', [start, end]);
              }
            },
            {
              text: '近10分钟',
              onClick(picker) {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - 600 * 1000);
                picker.$emit('pick', [start, end]);
              }
            },
            {
              text: '近一小时',
              onClick(picker) {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - 3600 * 1000);
                picker.$emit('pick', [start, end]);
              }
            },
            {
              text: '近一天',
              onClick(picker) {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - 3600 * 1000 * 24);
                picker.$emit('pick', [start, end]);
              }
            }, {
              text: '近一周',
              onClick(picker) {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
                picker.$emit('pick', [start, end]);
              }
            }, {
              text: '近一个月',
              onClick(picker) {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
                picker.$emit('pick', [start, end]);
              }
            }]
        },
        problemCauseOptions: [],
        problemCause: 'problemCause',
        statusOptions: [
          {
            label: "未解决",
            value: 0
          },
          {
            label: "已解决",
            value: 1
          },
          {
            label: "关闭",
            value: 2
          }
        ],
        activeName: 'problemPane',
        storeServiceNameKey: 'hawkEye:problemreocrd:storeServiceNameKey',
        storeAlarmTimesKey: 'hawkEye:problemreocrd:alarmDatePicker',
        storeProblemTimesKey: 'hawkEye:problemreocrd:problemDatePicker',
        storeStatusKey: 'hawkEye:problemreocrd:problemStatus',
        storeProblemLevelKey: 'hawkEye:problemreocrd:problemLevel',
        storeProblemCauseKey: 'hawkEye:problemreocrd:problemCause',
        storeDisposeUserKey: 'hawkEye:service:storeDisposeUserKey',
      };
    },
    created() {
      this.initQueryParams();
      this.getList();
      this.getProblemDictList();
      this.getUserList();
      this.getServiceNameList();
    },
    methods: {
      initQueryParams: function () {
        let picker1 = localStorage.getItem(this.storeAlarmTimesKey);
        let now = new Date()
        if (picker1) {
          try {
            let times = JSON.parse(picker1);
            let diff = new Date(times[1]).getTime() - new Date(times[0]).getTime();
            this.$set(this.queryParams, 'alarmTimes', [formatDate(new Date(now.getTime() - diff)), formatDate(now)])
          } catch (e) {
            localStorage.removeItem(this.storeAlarmTimesKey);
          }
        }
        let picker2 = localStorage.getItem(this.storeProblemTimesKey);
        if (picker2) {
          try {
            let times = JSON.parse(picker2);
            let diff = new Date(times[1]).getTime() - new Date(times[0]).getTime();
            this.$set(this.queryParams, 'recordTimes', [formatDate(new Date(now.getTime() - diff)), formatDate(now)]);
          } catch (e) {
            localStorage.removeItem(this.storeProblemTimesKey);
          }
        }
        let statusAsString = localStorage.getItem(this.storeStatusKey);
        if (statusAsString) {
          try {
            this.$set(this.queryParams, 'problemStatus', JSON.parse(statusAsString))
          } catch (e) {
            localStorage.removeItem(this.storeStatusKey);
          }
        }
        let levelAsString = localStorage.getItem(this.storeProblemLevelKey);
        if (levelAsString) {
          try {
            this.$set(this.queryParams, 'problemLevels', JSON.parse(levelAsString))
          } catch (e) {
            localStorage.removeItem(this.storeProblemLevelKey);
          }
        }
        let causeAsString = localStorage.getItem(this.storeProblemCauseKey);
        if (causeAsString) {
          try {
            this.$set(this.queryParams, 'problemCauses', JSON.parse(causeAsString))
          } catch (e) {
            localStorage.removeItem(this.storeProblemCauseKey);
          }
        }
        let serviceAsString = localStorage.getItem(this.storeServiceNameKey);
        if (serviceAsString) {
          try {
            this.$set(this.queryParams, 'serviceId', JSON.parse(serviceAsString))
          } catch (e) {
            localStorage.removeItem(this.storeServiceNameKey);
          }
        }
        let userIdAsString = localStorage.getItem(this.storeDisposeUserKey);
        if (userIdAsString) {
          try {
            this.$set(this.queryParams, 'disposeUser', JSON.parse(userIdAsString))
          } catch (e) {
            localStorage.removeItem(this.storeDisposeUserKey);
          }
        }
      },
      handleClick(tab, event) {

      },
      getProblemDictList() {
        this.getProblemLevelList();
        this.getProblemCauseList();
      },
      getProblemLevelList() {
        dictListByType(this.problemLevel).then(res => {
          this.problemLevelOptions = res.data;
        })
      },
      getProblemCauseList() {
        dictListByType(this.problemCause).then(res => {
          this.problemCauseOptions = res.data;
        })
      },
      getUserList() {
        userListNotSelf().then(res => {
          this.userOptions = res.data;
        })
      },
      getServiceNameList() {
        serviceNameList().then(res => {
          this.serviceOptions = res.data;
        })
      },
      /** 查询【请填写功能名称】列表 */
      getList() {
        this.loading = true;
        problemPageList(this.queryParams).then(res => {
          this.recordList = res.records;
          this.total = res.total;
        }).finally(() => {
          this.loading = false;
        });
      },
      handleResolve(row) {
        const ids = row.id || this.ids;
        this.$modal.confirm('是否标记为已解决(解决时间如果为空则默认当前时间)？').then(function () {
          return resolveProblem(ids);
        }).then(() => {
          this.getList();
          this.$modal.msgSuccess("操作成功");
        }).catch(() => {

        });
      },
      handleActivate(row) {
        const ids = row.id || this.ids;
        this.$modal.confirm('确认激活？').then(function () {
          return activateProblem(ids);
        }).then(() => {
          this.getList();
          this.$modal.msgSuccess("操作成功");
        }).catch(() => {

        });
      },
      // 取消按钮
      cancel() {
        this.open = false;
        this.reset();
      },
      // 表单重置
      reset() {
        this.form = {
          id: null,
          serviceId: null,
          traceId: null,
          alarmTime: null,
          disposeUser: null,
          problemName: null,
          problemCause: null,
          problemLevel: null,
          problemDesc: null,
          stackTrace: null
        };
        this.resetForm("form");
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.queryParams.pageNum = 1;
        this.getList();
      },
      /** 搜索按钮操作 */
      handleHighLevelQuery() {
        this.showHighLevelSearch = true;
      },
      /** 重置按钮操作 */
      resetQuery() {
        localStorage.removeItem(this.storeAlarmTimesKey);
        localStorage.removeItem(this.storeServiceNameKey);
        localStorage.removeItem(this.storeProblemTimesKey);
        localStorage.removeItem(this.storeProblemLevelKey);
        localStorage.removeItem(this.storeProblemCauseKey);
        localStorage.removeItem(this.storeStatusKey);
        localStorage.removeItem(this.storeDisposeUserKey);
        this.resetForm("queryForm");
        this.handleQuery();
      },
      // 多选框选中数据
      handleSelectionChange(selection) {
        this.ids = selection.map(item => item.id)
        this.single = selection.length !== 1
        this.multiple = !selection.length
      },
      /** 修改按钮操作 */
      handleUpdate(row) {
        this.$refs.modalForm.open(row, false);
      },
      handleStoreQueryParams(key, value) {
        if (value) {
          localStorage.setItem(key, JSON.stringify(value));
        } else {
          localStorage.removeItem(key);
        }
      },
      handleDict() {
        this.$refs.dictDrawer.open();
      },
      /** 提交按钮 */
      submitForm() {
        this.$refs["form"].validate(valid => {
          if (valid) {
            if (this.form.id != null) {
              updateProblem(this.form).then(response => {
                this.$modal.msgSuccess("修改成功");
                this.open = false;
                this.getList();
              });
            } else {
              addProblem(this.form).then(response => {
                this.$modal.msgSuccess("新增成功");
                this.open = false;
                this.getList();
              });
            }
          }
        });
      },
      /** 删除按钮操作 */
      handleDelete(row) {
        const ids = row.id || this.ids;
        this.$modal.confirm('是否确认删除选中数据项？').then(function () {
          return removeProblem(ids);
        }).then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        }).catch(() => {
        });
      },
      handleClose(row) {
        const ids = row.id || this.ids;
        this.$modal.confirm('是否关闭选中的缺陷？').then(function () {
          return closeProblem(ids);
        }).then(() => {
          this.getList();
          this.$modal.msgSuccess("关闭成功");
        }).catch(() => {
        });
      },
      // 复制成功回调函数
      copySuccessHandle(value) {
        this.$modal.msgSuccess("内容已复制到剪切板,可进行粘贴");
      },
      // 复制失败回调函数
      copyErrorHandle(value) {
        this.$modal.msgError("复制失败,请确认浏览器支持复制功能");
      },
      exportTxt() {
        this.download('/hawk-eye/log/export-log-txt?id=' + this.form.id, {}, `告警日志_${new Date().getTime()}.txt`)
      },
      handleDoc() {
        let url = 'https://www.wolai.com/nEM7PC9TMuZ1iJQEFN9dTd';
        if (!url) {
          return;
        }
        window.open(url);
      }
    }
  };
</script>
<style scoped="css">
  .scroll-container {
    height: 260px; /* 设置容器的高度 */
    overflow: auto; /* 或者可以使用 overflow: scroll; */
  }

  .el-tag--dark::v-deep {
    border-color: #ffffff;
    color: #ffffff;
  }

</style>
